﻿
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
#if !NETCOREAPP
using System.Web;
using System.Web.Mvc;
using System.Web.WebPages;
    using System.Web.Mvc.Html;

#endif

#if NETCOREAPP
using Microsoft.AspNetCore.Mvc.Razor;
using Microsoft.AspNetCore.Mvc.Rendering;
using Kugar.Core.Web;
using Microsoft.AspNetCore.Http.Extensions;
#endif
using Kugar.Core.BaseStruct;
using Kugar.Core.ExtMethod;
using Kugar.MVC.MobileUI.WeUI.Helpers;


namespace Kugar.MVC.MobileUI.WeUI.PageControls.PageCommons
{
    public class PageCommon_ListViewContainer<TData>:ContainerBase
    {
        private string _callOnRefresh = "";
        private string _callOnLoadMore = "";
        private Func<TData, string> _rowIDGetter = null;
        private int _currentIndex = 0;
        private TData _currentData = default(TData);
        private IEnumerable<TData> _data = null;
        private List<ListViewItemTemplateBase<TData>> _templates=new List<ListViewItemTemplateBase<TData>>(2);
        private string _loadMoreUrl = "";
        private string _refreshDataUrl = "";
        private string _loadMorePageIndexKey = "";
        private int _currentPageIndex = 1;

        public PageCommon_ListViewContainer(ViewContext viewContext) : base(viewContext)
        {
            this.Css(" weui-panel weui-panel_access weui-listview");
        }

        public PageCommon_ListViewContainer<TData> Data(IEnumerable<TData> data)
        {
            _data = data;

            return this;
        }

        public PageCommon_ListViewContainer<TData> Data(VM_PagedList<TData> data)
        {
            _data = data.Data;
            _currentPageIndex = data.PageIndex;

            return this;
        }


        /// <summary>
        /// 添加一个图文框
        /// </summary>
        /// <returns></returns>
        public ListViewItemMediaBox<TData> AddMediaBoxTemplate()
        {
            var template = new ListViewItemMediaBox<TData>(this);

            template.ListView = this;

            _templates.Add(template);

            return template;
        }

        /// <summary>
        /// 添加一个可自定义文本区域输出内容的图文框
        /// </summary>
        /// <returns></returns>
        public ListViewItemCustomMediaBox<TData> AddCustomMediaBox()
        {
            var template = new ListViewItemCustomMediaBox<TData>(this);

            template.ListView = this;

            _templates.Add(template);

            return template;

            return new ListViewItemCustomMediaBox<TData>(this);
        }

        /// <summary>
        /// 添加一个完全自定义输出的模板
        /// </summary>
        /// <returns></returns>
        public ListViewItemEmptyTempalte<TData> AddCustomRender()
        {
            var template = new ListViewItemEmptyTempalte<TData>(this);

            template.ListView = this;

            _templates.Add(template);

            return template;

            return new ListViewItemEmptyTempalte<TData>(this);
        }

        
        public ListViewItemGridBox<TData> AddGridBox()
        {
            var template = new ListViewItemGridBox<TData>(this);

            template.ListView = this;

            _templates.Add(template);

            return template;

            return new ListViewItemGridBox<TData>(this);
        }


        /// <summary>
        /// 设置每行的行ID获取函数
        /// </summary>
        /// <param name="rowIDGetter"></param>
        /// <returns></returns>
        public PageCommon_ListViewContainer<TData> SetRowIDFunc(Func<TData, string> rowIDGetter)
        {
            _rowIDGetter = rowIDGetter;

            return this;
        }

        /// <summary>
        /// 允许下拉刷新,并需设置触发脚本,注意:如果配合tabbar或者navbar,请使用外层容器的下拉刷新功能
        /// </summary>
        /// <param name="callOnRefresh"></param>
        /// <returns></returns>
        public PageCommon_ListViewContainer<TData> EnablePullToRefresh(string url = "", string pageIndexKey = "pageindex", string callOnNeedOrSuccessCallback = "")
        {
            if (string.IsNullOrWhiteSpace(url))
            {
#if NETCOREAPP
                url = ViewContext.HttpContext.Request.GetDisplayUrl().ToUri().RemoveQuery(pageIndexKey).ToStringEx();
#endif
#if !NETCOREAPP
      url = ViewContext.RequestContext.HttpContext.Request.RawUrl.ToUri().RemoveQuery(pageIndexKey).ToStringEx();
#endif


            }

            _refreshDataUrl = url;
            _loadMorePageIndexKey = pageIndexKey;

            _callOnRefresh = callOnNeedOrSuccessCallback;

            return this;
        }

        /// <summary>
        /// 允许滚动加载,并需设置触发脚本,注意:如果配合tabbar或者navbar,请使用外层容器的滚动加载
        /// </summary>
        /// <param name="callOnNeed"></param>
        /// <returns></returns>
        public PageCommon_ListViewContainer<TData> EnableLoadingMore(string url="", string pageIndexKey = "pageindex", string callOnNeedOrSuccessCallback="")
        {
            if (string.IsNullOrWhiteSpace(url))
            {
#if NETCOREAPP
                url = ViewContext.HttpContext.Request.GetDisplayUrl().ToUri().RemoveQuery(pageIndexKey).ToStringEx();
#endif
#if !NETCOREAPP
      url = ViewContext.RequestContext.HttpContext.Request.RawUrl.ToUri().RemoveQuery(pageIndexKey).ToStringEx();
#endif
            }

            _callOnLoadMore = callOnNeedOrSuccessCallback;

            _loadMoreUrl = url;
            _loadMorePageIndexKey = pageIndexKey;
            
            return this;
        }

        public TData CurrentRowData => _currentData;

        public string CurrentRowID
        {
            get
            {
                if (_rowIDGetter==null)
                {
                    throw new ArgumentNullException("rowIDGetter","未设置行ID获取函数");
                }

                return _rowIDGetter(_currentData);
            }
        }

        public int CurrentIndex => _currentIndex;

        public override void Dispose()
        {
            foreach (var template in _templates)
            {
                _currentIndex = 0;

                var con = template.RenderTemplateContainer();

                foreach (var item in _data)
                {
                    _currentIndex++;

                    _currentData = item;

                    ViewContext.Writer.WriteLine(template.Render(_currentData));
                }

                con?.Dispose();
            }

            ViewContext.Writer.WriteLine("</div> <!-- end panel__bd -->");
            ViewContext.Writer.WriteLine("</div> <!-- end weui-panel -->");

            //if (!string.IsNullOrWhiteSpace(_callOnLoadMore))
            //{
            //    ViewContext.Writer.WriteLine("<div class=\"weui-loadmore\"><i class=\"weui-loading\"></i><span class=\"weui-loadmore__tips\">正在加载</span></div>");
            //}
            
        }

        private ContainerBase _templateContainer = null;

        internal override ContainerBase RenderInternal()
        {

            if (_data == null)
            {
                throw new ArgumentNullException("Data");
            }

            if (!string.IsNullOrWhiteSpace(_callOnRefresh) || !string.IsNullOrWhiteSpace(_loadMoreUrl))
            {
                this.Data("onpulltorefresh", _callOnRefresh);

                this.Css("pullToRefreshCollection");

                this.Data("refreshurl", _loadMoreUrl)
                    .Data("pageindexkey", _loadMorePageIndexKey)
                    .Data("pageindex", _currentPageIndex.ToString())
                    ;
            }

            if (!string.IsNullOrWhiteSpace(_callOnLoadMore) || !string.IsNullOrWhiteSpace(_loadMoreUrl))
            {
                this.Data("loadmore", "True");
                this.Data("loadmorecallback", _callOnLoadMore);

                this.Data("loadmoreurl", _loadMoreUrl)
                    .Data("pageindexkey", _loadMorePageIndexKey)
                    .Data("pageindex",_currentPageIndex.ToString())
                    ;
            }

            //if (!string.IsNullOrWhiteSpace(_callOnLoadMore))
            //{
            //    this.Data("callonloadmore", _callOnLoadMore);
            //}
            
            ViewContext.Writer.WriteLine($"<div {_attrs}>");
            
            ViewContext.Writer.WriteLine("<div class=\"weui-panel__bd\">");

            
            return this;
        }
    }
    
    public abstract class ListViewItemTemplateBase<TData>
    {
        protected ListViewItemTemplateBase(PageCommon_ListViewContainer<TData> listview)
        {
            ListView = listview;
        }

        public PageCommon_ListViewContainer<TData> ListView { get; internal set; }

        public virtual ContainerBase RenderTemplateContainer()
        {
            return null;
        }

        internal abstract string Render(TData data);

        public override string ToString()
        {
            return String.Empty;
            return base.ToString();
        }
    }

    public class ListViewItemEmptyTempalte<TData> : ListViewItemTemplateBase<TData>
    {
        private Func<string, MvcHtmlString> _starttemplate = null;
        private Func<string, MvcHtmlString> _endTemplate = null;
        private Func<TData, HelperResult> _render = null;

        public override ContainerBase RenderTemplateContainer()
        {
            return new EmptyContainer(ListView.ViewContext,_starttemplate,_endTemplate);
        }

        public ListViewItemEmptyTempalte<TData> StartTemplateContainer(Func<string, MvcHtmlString> template)
        {
            _starttemplate = template;
            return this;
        }

        public ListViewItemEmptyTempalte<TData> EndTemplateContainer(Func<string, MvcHtmlString> template)
        {
            _endTemplate = template;

            return this;
        }

        public ListViewItemEmptyTempalte<TData> CustomRender(Func<TData, HelperResult> template)
        {
            _render = template;
            return this;
        }

        internal override string Render(TData data)
        {
            return _render?.Invoke(data).ToHtmlString();
        }

        private class EmptyContainer:ContainerBase
        {
            private Func<string, MvcHtmlString> _starttemplate = null;
            private Func<string, MvcHtmlString> _endTemplate = null;


            public EmptyContainer(ViewContext viewContext, Func<string, MvcHtmlString> starttemplate, Func<string, MvcHtmlString> endTemplate) : base(viewContext)
            {
                _starttemplate = starttemplate;
                _endTemplate = endTemplate;
            }

            public override void Dispose()
            {
                _endTemplate?.Invoke("");
            }

            internal override ContainerBase RenderInternal()
            {
                _starttemplate?.Invoke("");

                return this;
            }
        }

        public ListViewItemEmptyTempalte(PageCommon_ListViewContainer<TData> listview) : base(listview)
        {
        }
    }

    /// <summary>
    /// ListView的图文模板,一个图标+两行左侧文本+一个右侧文本(聊天模式)
    /// </summary>
    /// <typeparam name="TData"></typeparam>
    public class ListViewItemMediaBox<TData>: ListViewItemTemplateBase<TData>
    {
        private Func<TData, string> _iconGetter = null;
        private Func<TData, string> _titleGetter = null;
        private Func<TData, string> _descGetter = null;
        private Func<TData, string> _rightTitleGetter = null;
        private Func<TData, string> _badgeGetter = null;
        private Func<TData, string> _linkGetter = null;
        private string _iconSize = "50px";

        public ListViewItemMediaBox(PageCommon_ListViewContainer<TData> listview) : base(listview)
        {
        }

        public ListViewItemMediaBox<TData> Title(Func<TData, string> titleGetter)
        {
            _titleGetter = titleGetter;

            return this;
        }

        public ListViewItemMediaBox<TData> Title(Func<TData, HelperResult> titleGetter)
        {
            _titleGetter = (data) => titleGetter(data).ToHtmlString();

            return this;
        }

        public ListViewItemMediaBox<TData> Icon(Func<TData, string> iconGetter)
        {
            _iconGetter = iconGetter;

            return this;
        }

        public ListViewItemMediaBox<TData> Desc(Func<TData, HelperResult> descGetter)
        {
            _descGetter = (data) => descGetter(data).ToHtmlString();

            return this;
        }

        public ListViewItemMediaBox<TData> Desc(Func<TData, string> descGetter)
        {
            _descGetter = descGetter;

            return this;
        }

        public ListViewItemMediaBox<TData> RightTitle(Func<TData, string> rightTitleGetter)
        {
            _rightTitleGetter = rightTitleGetter;

            return this;
        }

        public ListViewItemMediaBox<TData> Badge(Func<TData, string> badgeGetter)
        {
            _badgeGetter = badgeGetter;

            return this;
        }

        public ListViewItemMediaBox<TData> Link(Func<TData, string> linkGetter)
        {
            _linkGetter = linkGetter;

            return this;
        }

        public ListViewItemMediaBox<TData> IconSize(string iconSize = "80px")
        {
            _iconSize = iconSize;

            return this;
        }

        internal override string Render(TData data)
        {
            /*
              <a href="javascript:void(0);" class="weui-media-box weui-media-box_appmsg">
                <div class="weui-media-box__hd">
                  <img class="weui-media-box__thumb" src="" alt="">
                </div>
                <div class="weui-media-box__bd">
                  <h4 class="weui-media-box__title">标题一</h4>
                  <p class="weui-media-box__desc">由各种物质组成的巨型球状天体，叫做星球。星球有一定的形状，有自己的运行轨道。</p>
                </div>
              </a>
             */

            var sb = new StringBuilder(256);

            sb.AppendLine(
                $"<div class=\"weui-media-box weui-media-box_appmsg\">");

            var iconUrl = _iconGetter?.Invoke(data);

            if (!string.IsNullOrWhiteSpace(iconUrl))
            {
                sb.AppendLine("<div class=\"weui-media-box__hd\">");

                if (!string.IsNullOrWhiteSpace(iconUrl))
                {
                    sb.AppendLine($"<img class=\"weui-media-box__thumb\" src=\"{iconUrl}\" width=\"{_iconSize}\" height=\"{_iconSize}\" alt=\"\" />");
                }

                var badge = _badgeGetter?.Invoke(data) ?? "";

                if (!string.IsNullOrWhiteSpace(badge))
                {
                    sb.AppendLine(
                        $"<span class=\"weui-badge\" style=\"position: absolute;top: -.4em;right: -.4em;\">{badge}</span>");
                }

                sb.AppendLine("</div> <!-- end box__hd -->");
            }

            
            


            sb.AppendLine("<div class=\"weui-media-box__bd\">");
            sb.AppendLine($"<h4 class=\"weui-media-box__title\">{_titleGetter?.Invoke(data)??""}");
            sb.AppendLine($"<span class=\"weui-media-box__title-after\">{_rightTitleGetter?.Invoke(data)??""}</span>");
            sb.AppendLine("</h4>");


            sb.AppendLine($"<p class=\"weui-media-box__desc\">{_descGetter?.Invoke(data) ?? ""}</p>");
            sb.AppendLine("</div> <!-- end  box__bd-->");
            sb.AppendLine("</div>");

            var value = sb.ToString();

            sb.Clear();
            
            return value;
        }
        
    }

    /// <summary>
    /// ListView的自定义图文模板,一个图标+右侧文本区域自定义输出,,模板只保留图标,badge和link,自定义内容将输出在weui-media-box__bd中
    /// </summary>
    /// <typeparam name="TData"></typeparam>
    public class ListViewItemCustomMediaBox<TData> : ListViewItemTemplateBase<TData>
    {
        private Func<TData, string> _iconGetter = null;
        private Func<TData, string> _badgeGetter = null;
        private Func<TData, string> _linkGetter = null;
        private Func<TData,HelperResult> _customRender=null;

        public ListViewItemCustomMediaBox(PageCommon_ListViewContainer<TData> listview) : base(listview)
        {
        }
        

        public ListViewItemCustomMediaBox<TData> Icon(Func<TData, string> iconGetter)
        {
            _iconGetter = iconGetter;

            return this;
        }
        
        public ListViewItemCustomMediaBox<TData> Badge(Func<TData, string> badgeGetter)
        {
            _badgeGetter = badgeGetter;

            return this;
        }

        public ListViewItemCustomMediaBox<TData> Link(Func<TData, string> linkGetter)
        {
            _linkGetter = linkGetter;

            return this;
        }

        public ListViewItemCustomMediaBox<TData> CustomRender(Func<TData, HelperResult> render)
        {
            _customRender = render;

            return this;
        }

        internal override string Render(TData data)
        {
            /*
              <a href="javascript:void(0);" class="weui-media-box weui-media-box_appmsg">
                <div class="weui-media-box__hd">
                  <img class="weui-media-box__thumb" src="" alt="">
                </div>
                <div class="weui-media-box__bd">
                  <h4 class="weui-media-box__title">标题一</h4>
                  <p class="weui-media-box__desc">由各种物质组成的巨型球状天体，叫做星球。星球有一定的形状，有自己的运行轨道。</p>
                </div>
              </a>
             */

            var sb = new StringBuilder(256);

            sb.AppendLine(
                $"<a href=\"{_linkGetter.Invoke(data) ?? "javascript:void(0);"}\" class=\"weui-media-box weui-media-box_appmsg\">");

            sb.AppendLine($"<div class=\"weui-media-box__hd\"><img class=\"weui-media-box__thumb\" src=\"{_iconGetter?.Invoke(data)}\" alt=\"\" />");

            var badge = _badgeGetter?.Invoke(data) ?? "";

            sb.AppendLine(
                $"<span class=\"weui-badge\" style=\"position: absolute;top: -.4em;right: -.4em; {badge.IfEmptyOrWhileSpace("display:none;")}\">{badge}</span>");
        
            sb.AppendLine("</div> <!-- end box__hd -->");
            

            sb.AppendLine("<div class=\"weui-media-box__bd\">");

            sb.AppendLine(_customRender?.Invoke(data)?.ToHtmlString());
            
            sb.AppendLine("</div> <!-- end  box__bd-->");
            
            sb.AppendLine("</a>");

            var value = sb.ToString();

            sb.Clear();

            return value;
        }

    }

    public class ListViewItemGridBox<TData> : ListViewItemTemplateBase<TData>
    {
        internal Func<TData, string> _titleGetter=null;
        internal Func<TData, string> _iconUrl = null;
        internal Func<TData, string> _href = null;
        internal Func<TData, string> _clickScript = null;
        private Func<TData, string> _badgeGetter = null;

        public ListViewItemGridBox(PageCommon_ListViewContainer<TData> listview) : base(listview)
        {
        }

        public ListViewItemGridBox<TData> Title(Func<TData,string> titleGetter)
        {
            _titleGetter = titleGetter;

            return this;
        }

        public ListViewItemGridBox<TData> Title(Func<TData, HelperResult> titleGetter)
        {
            _titleGetter = (data) => titleGetter(data).ToHtmlString();
            
            return this;
        }

        public ListViewItemGridBox<TData> Icon(Func<TData,string> iconUrlGetter)
        {
            _iconUrl = iconUrlGetter;

            return this;
        }

        /// <summary>
        /// 点击后的跳转链接
        /// </summary>
        /// <param name="href"></param>
        /// <returns></returns>
        public ListViewItemGridBox<TData> Href(Func<TData,string> href)
        {
            _href = href;
            _clickScript = null;

            return this;
        }

        /// <summary>
        /// 点击按钮时的操作,与Href二选一
        /// </summary>
        /// <param name="clickScript"></param>
        /// <returns></returns>
        public ListViewItemGridBox<TData> OnClick(Func<TData,string> clickScript)
        {
            _clickScript = clickScript;
            _href = null;

            return this;
        }

        /// <summary>
        /// 输出数据的角标,如果返回空字符串,则角标隐藏,可用于输出数字或者角标文本
        /// </summary>
        /// <param name="badgeGetter"></param>
        /// <returns></returns>
        public ListViewItemGridBox<TData> Badge(Func<TData, string> badgeGetter)
        {
            _badgeGetter = badgeGetter;

            return this;
        }

        internal override string Render(TData data)
        {
            /*
             <a href="" class="weui-grid js_grid">
                <span class="weui-badge" style="position: absolute;top: -.4em;right: 0.4em;z-index: 99;display: none;">8</span>
                <div class="weui-grid__icon">
                    <img src="images/icon_nav_button.png" alt="">
                </div>
                <p class="weui-grid__label">
                    Button
                </p>
            </a>
             */

            var sb =new StringBuilder();

            var href = _href?.Invoke(data);
            var badge = _badgeGetter?.Invoke(data);


            sb.AppendLine($"<a {href.IsNotNullOrEmpty().If($"href=\"{href}\"")} onclick=\"{_clickScript?.Invoke(data)}\" class=\"weui-grid js_grid\">");
            sb.AppendLine(
                $"<span class=\"weui-badge\" style=\"position: absolute;top: 0em;right: 0.0em;z-index: 99; {badge.IsEmptyOrWhileSpace().If("display: none;")}\">{badge}</span>");
            sb.AppendLine("<div class=\"weui-grid__icon\">");
            sb.AppendLine($"<img src=\"{_iconUrl?.Invoke(data)}\" alt=\"\">");
            sb.AppendLine("</div> <!-- end grid__icon -->");

            var title = "";

            if (_titleGetter!=null)
            {
                title = _titleGetter(data);
            }
 

            sb.AppendLine($"<div class=\"weui-grid__label\">{title}</div>");
            sb.AppendLine("</a>");

            var value = sb.ToString();

            sb.Clear();

            return value;
        }

        public override ContainerBase RenderTemplateContainer()
        {
            return new GridContainer(ListView.ViewContext).Render();
        }


        private class GridContainer : ContainerBase
        {
            public GridContainer(ViewContext viewContext) : base(viewContext)
            {
                _attrs.Class("weui-grids");
                this.Style("overflow", "initial");
            }

            public override void Dispose()
            {
                ViewContext.Writer.WriteLine("</div> <!-- end gridscontainer -->");
            }

            internal override ContainerBase RenderInternal()
            {
                ViewContext.Writer.WriteLine("<div class=\"weui-grids weui-listview-gridscontainer\">");

                return this;
            }
        }
    }

}